package com.ticket.sass.admin.service.impl;


import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ticket.sass.admin.dto.input.SaleFilmListInput;
import com.ticket.sass.admin.dto.input.film.FilmScheduleListInput;
import com.ticket.sass.admin.mapper.FilmScheduleMapper;
import com.ticket.sass.admin.service.BaseService;
import com.ticket.sass.common.entity.tenant.FilmScheduleEntity;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author ywb
 * @since 2024-03-06
 */
@Service
public class FilmScheduleServiceImpl extends ServiceImpl<FilmScheduleMapper, FilmScheduleEntity> implements BaseService<FilmScheduleEntity> {
    
    /**
     * key 为 排期ID 值 为 影片ID
     * @param ids 排期ID列表
     * @return Map<Long, Long> 其中key为排期ID，值为影片ID
     */
    public Map<Long, Long> getFilmSchedulesByIds(List<Long> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            return new HashMap<>();
        }
        
        QueryWrapper<FilmScheduleEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("id", ids);
        queryWrapper.select("id", "film_id"); // 只查询id和film_id字段
        List<FilmScheduleEntity> filmSchedules = this.baseMapper.selectList(queryWrapper);
        
        return filmSchedules.stream()
            .collect(Collectors.toMap(FilmScheduleEntity::getId, FilmScheduleEntity::getFilmId));
    }
    /**
     * 查询在售影片 影片分组 放映时间在 当前时间之后
     */
    public List<FilmScheduleEntity> getOnSaleFilms(SaleFilmListInput input) {
        QueryWrapper<FilmScheduleEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.ge("start_time", LocalDateTime.now());
        queryWrapper.like(StrUtil.isNotEmpty(input.getFilmName()), "film_name", input.getFilmName());
        queryWrapper.orderByDesc("film_id", "start_time");
        
        // 查询数据库，获取符合条件的影片列表
        List<FilmScheduleEntity> filmList = this.list(queryWrapper);
        return new ArrayList<>(filmList.stream()
            .collect(Collectors.toMap(FilmScheduleEntity::getFilmName, Function.identity(), (existing, replacement) -> existing))
            .values());
    }
    
    
    public IPage<FilmScheduleEntity> iPage(FilmScheduleListInput input,  Long cinemaId) {
        Page<FilmScheduleEntity> page = new Page<>(input.getPageNum(), input.getPageSize());
        QueryWrapper<FilmScheduleEntity> queryWrapper = buildQueryWrapper(entityClass, input);
        queryWrapper.orderByDesc("id");
        queryWrapper.eq("cinema_id", cinemaId);
        queryWrapper.between(Objects.nonNull(input.getStartTime()), "start_time", input.getStartTime(), input.getEndTime());
        queryWrapper.in(Objects.nonNull(input.getHallIds()) && input.getHallIds().size() > 0, "hall_id", input.getHallIds());
        queryWrapper.in(Objects.nonNull(input.getFilmIds()) && input.getFilmIds().size() > 0, "film_id", input.getFilmIds());
        return page(page, queryWrapper);
    }

    public List<String> sessionCode(Long cinemaId){
        QueryWrapper<FilmScheduleEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("cinema_id", cinemaId);
        queryWrapper.select("session_code");
        return listObjs(queryWrapper, Object::toString);
    }
    
    public void updateFilmIdByFilmCodeAndCinemaId(Map<String, Long> filmCodeToFilmIdMap, Long cinemaId) {
        filmCodeToFilmIdMap.forEach((filmCode, filmId) -> baseMapper.updateFilmIdByFilmCodeAndCinemaId(filmCode, filmId, cinemaId));
    }
    public void updateHallIdByHallCodeAndCinemaId(Map<String, Long> hallIdCodeMap, Long cinemaId) {
        hallIdCodeMap.forEach((hallCode, hallId) -> baseMapper.updateHallIdByHallCodeAndHallId(hallCode, hallId, cinemaId));
    }
    public void updateSalePriceById(Long id, BigDecimal salePrice) {
        UpdateWrapper<FilmScheduleEntity> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", id);
        updateWrapper.set("sale_price", salePrice);
        this.update(updateWrapper);
    }
    
    /**
     * 根据影院ID查询未开场的排期列表
     * @param cinemaId 影院ID
     * @return 未开场的排期列表
     */
    public List<FilmScheduleEntity> selectUnstartedSchedulesByCinemaId(Long cinemaId) {
        // 创建查询条件
        QueryWrapper<FilmScheduleEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
            .eq(FilmScheduleEntity::getCinemaId, cinemaId) // 匹配影院ID
            .gt(FilmScheduleEntity::getStartTime, LocalDateTime.now()) // 放映时间大于当前时间，即未开场
            .orderByAsc(FilmScheduleEntity::getStartTime); // 按放映时间升序排列
        
        // 执行查询
        return this.list(queryWrapper);
    }
    
    /**
     * 根据影院ID查询未开场的排期列表
     * @param cinemaId 影院ID
     * @return 未开场的排期列表
     */
    public List<String> filmCodeByNow(Long cinemaId, List<String> filterFilmCode) {
        // 创建查询条件
        QueryWrapper<FilmScheduleEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
            .eq(FilmScheduleEntity::getCinemaId, cinemaId) // 匹配影院ID
            .gt(FilmScheduleEntity::getStartTime, LocalDateTime.now()) // 放映时间大于当前时间，即未开场
            .notIn(filterFilmCode.size() > 0, FilmScheduleEntity::getFilmCode, filterFilmCode)
            .select(FilmScheduleEntity::getFilmCode); // 选择film_code字段
        
        // 执行查询
        return this.baseMapper.selectList(queryWrapper).stream()
            .map(FilmScheduleEntity::getFilmCode) // 从查询结果中提取film_code
            .collect(Collectors.toList()); // 收集结果到列表中
    }
}
